Traverse level 2 objects

Hi,

I'm new to dxl programming, and are in desperately need of a solution to my problem.
I need to count the number of failed test for each "Test set" (see attached screen dump) in a test procedure/report and print the number in the column named "No of failed test".
More specifically, it means to sum up all "Test Result" that equals "Failed" between level 2 objects (e.g. Failed between heading 4.2 and 4.3 equals 1 and Failed between heading 4.3 and 4.4 equals 2).

I have tried with a for-loop and I'm able to detect level 2 objects, but how do i loop from here until next level 2 object and count the numbers of Failed test in between, and continue to the next level 2 object?

I hope someone is able to help my quickly :-)

Regards,
Klaus
KlausV - Thu Jun 07 06:07:09 EDT 2012

Re: Traverse level 2 objects
PatrickGuay - Thu Jun 07 10:21:29 EDT 2012

In order to filter level 2 headings do something like the following:
 

outlining on;
level 1;
       
          Array level_1_headings = create(10,1)
          int index=0;
 
           
           Object o1 = null;
           for o1 in mod do {
                 println("\nObject Heading: " o1."Object Heading" "\t Object Text: " o1."Object Text" "")
                        put(level_1_headings, o1."Object Heading" "", 0, index++)
           } outlining off;
level 0;

 


This gets all level 1 headings and prints them using my java like println function. You will want to use level 2 instead of level 1 however keep the level 0 in order to come back to all objects if you have to manipulate the child objects and not only the headings.

Patrick

 

Re: Traverse level 2 objects
llandale - Thu Jun 07 13:08:59 EDT 2012

So you have "Test Set" objects that have subordinate "Test Procedure" objects. You want to set "Test Set" summary attributes based on values of its "Test Procedure" objects. Sounds reasonable.

The key to this is the "for o1 in o2 do" loop, which finds each subsequent child object of o2.

First off, so far I have NEVER used an sort of filter for this kind of problem and do not intend to start now. Here's an outline:

void MakeTestSetSummary(Object oTS)
{    // for the specified TestSet object, get info from its subordinate Test Procedures and set the summary attributes of the Test Set
   if (null oTS) then return
   if (oTS is not really a Test Set) then return
   iPassed = 0
   iFailed = 0
   iUnknown = 0
   for oTP in oTS do
   {  if (oTP is "passed") then iPassed++
      elseif(oTP is "Failed") then iFailed++
      else iUnknown++
   }
   set oTS attributes iPassed, iFailed, iUnknown
}  // MakeTestSetSummary()
 
//   MAIN
for o in entire mod do
{  if (isDeleted(o)) then continue
   if (o disqualifies for other reason's) then continue
   if (o is not a TestSet) then continue
   MakeTestSetSummary(o)
}


Actually, I would do this with an Attr-DXL:

 

define MakeTestSetSummary() above; except using oTS.whatever = Results
if (obj is not a TestSet) //
then obj.attrDXLName = ""
else MakeTestSetSummary(obj)


-Louie

 

Re: Traverse level 2 objects
KlausV - Fri Jun 08 08:43:53 EDT 2012

llandale - Thu Jun 07 13:08:59 EDT 2012

So you have "Test Set" objects that have subordinate "Test Procedure" objects. You want to set "Test Set" summary attributes based on values of its "Test Procedure" objects. Sounds reasonable.

The key to this is the "for o1 in o2 do" loop, which finds each subsequent child object of o2.

First off, so far I have NEVER used an sort of filter for this kind of problem and do not intend to start now. Here's an outline:

void MakeTestSetSummary(Object oTS)
{    // for the specified TestSet object, get info from its subordinate Test Procedures and set the summary attributes of the Test Set
   if (null oTS) then return
   if (oTS is not really a Test Set) then return
   iPassed = 0
   iFailed = 0
   iUnknown = 0
   for oTP in oTS do
   {  if (oTP is "passed") then iPassed++
      elseif(oTP is "Failed") then iFailed++
      else iUnknown++
   }
   set oTS attributes iPassed, iFailed, iUnknown
}  // MakeTestSetSummary()
 
//   MAIN
for o in entire mod do
{  if (isDeleted(o)) then continue
   if (o disqualifies for other reason's) then continue
   if (o is not a TestSet) then continue
   MakeTestSetSummary(o)
}


Actually, I would do this with an Attr-DXL:

 

define MakeTestSetSummary() above; except using oTS.whatever = Results
if (obj is not a TestSet) //
then obj.attrDXLName = ""
else MakeTestSetSummary(obj)


-Louie

 

Hi,

Thank you both very much for answering :-)

I have tried the suggestion from Ilandale, but I can't make it work ;-( The suggestion is by the way very similar to my own attempt.
I have tried to simplify the dxl script further in order to try to figure out whats going on.
Object o = null
Object oTP = null
int iCount = 0

int MakeTestSetSummary(Object oTS)
{
if (null oTS) then return -88
iCount = 0
for oTP in oTS do
{
iCount++
}
return iCount
}

// main
if (level(obj) == 2)
{
obj.attrDXLName = MakeTestSetSummary(obj)
}
else
{
obj.attrDXLName = -1
}

Ass it can be seen from the attached file, the output for heading 4.1 and heading 4.2 are both 2 and 1 for heading 4.3.
It seems to me that the loop "for oTP in oTS do" runs only on level 3 headings (one level below selected level 2 from main)?

I need the for-sentence to run on each object below, regardless of level.

How do I do that?

Thanks
Klaus
Attachments

attachment_14833211_Output.jpg

Re: Traverse level 2 objects
llandale - Fri Jun 08 15:29:34 EDT 2012

KlausV - Fri Jun 08 08:43:53 EDT 2012
Hi,

Thank you both very much for answering :-)

I have tried the suggestion from Ilandale, but I can't make it work ;-( The suggestion is by the way very similar to my own attempt.
I have tried to simplify the dxl script further in order to try to figure out whats going on.
Object o = null
Object oTP = null
int iCount = 0

int MakeTestSetSummary(Object oTS)
{
if (null oTS) then return -88
iCount = 0
for oTP in oTS do
{
iCount++
}
return iCount
}

// main
if (level(obj) == 2)
{
obj.attrDXLName = MakeTestSetSummary(obj)
}
else
{
obj.attrDXLName = -1
}

Ass it can be seen from the attached file, the output for heading 4.1 and heading 4.2 are both 2 and 1 for heading 4.3.
It seems to me that the loop "for oTP in oTS do" runs only on level 3 headings (one level below selected level 2 from main)?

I need the for-sentence to run on each object below, regardless of level.

How do I do that?

Thanks
Klaus

Yes the [for oChild in oParent do] loop only finds child objects directly under oParent; I see under 4.1 you have only 4.1.1 and 4.1.2; no 4.1.3; thus Test is "2". In order to get lower objects also you'll need some recursion.

int   CountTestProcedures(Object oParent)
{   // Count all the Test Summary objects under this Parent object, anywhere in its hierarchy
    // Function is RECURSIVE
    if (null oParent) return(0)
    Object oChild
    int Count = 0
    for oChild in oParent do
    {  if (oChild is a Test Procedure) then Count++
       Count += CountTestProcedures(oChild)   // RECURSION
    }
    return(Count)
}  // end recursive CountTestProcedures()
 
int MakeTestSetSummary(Object oTS)
{   if (null oTS or oTS is not a TestSummary) then return(-88)
    return(CountTestProcedures(oTS)
}


This simple case with count is too easy, its a little harder when dealing with string or other results:

 

void CountTestProcedures(Object oParent, SomeDataStructure &Results)
{   // Accumulate Results of all the Test Summary objects under this Parent object, anywhere in its hierarchy
    // Function is RECURSIVE
    if (null oParent) return(0)
    Object oChild
    for oChild in oParent do
    {  if (oChild is a Test Procedure) then Add some info of oChild to Results
       CountTestProcedures(oChild)   // RECURSION
    }
}  // end recursive CountTestProcedures()
 
int MakeTestSetSummary(Object oTS)
{   if (null oTS or oTS is not a TestSummary) then return(-1)
    return(CountTestProcedures(oTS)
}


-Louie

 

Re: Traverse level 2 objects
KlausV - Mon Jun 11 08:48:55 EDT 2012

llandale - Fri Jun 08 15:29:34 EDT 2012

Yes the [for oChild in oParent do] loop only finds child objects directly under oParent; I see under 4.1 you have only 4.1.1 and 4.1.2; no 4.1.3; thus Test is "2". In order to get lower objects also you'll need some recursion.

int   CountTestProcedures(Object oParent)
{   // Count all the Test Summary objects under this Parent object, anywhere in its hierarchy
    // Function is RECURSIVE
    if (null oParent) return(0)
    Object oChild
    int Count = 0
    for oChild in oParent do
    {  if (oChild is a Test Procedure) then Count++
       Count += CountTestProcedures(oChild)   // RECURSION
    }
    return(Count)
}  // end recursive CountTestProcedures()
 
int MakeTestSetSummary(Object oTS)
{   if (null oTS or oTS is not a TestSummary) then return(-88)
    return(CountTestProcedures(oTS)
}


This simple case with count is too easy, its a little harder when dealing with string or other results:

 

void CountTestProcedures(Object oParent, SomeDataStructure &Results)
{   // Accumulate Results of all the Test Summary objects under this Parent object, anywhere in its hierarchy
    // Function is RECURSIVE
    if (null oParent) return(0)
    Object oChild
    for oChild in oParent do
    {  if (oChild is a Test Procedure) then Add some info of oChild to Results
       CountTestProcedures(oChild)   // RECURSION
    }
}  // end recursive CountTestProcedures()
 
int MakeTestSetSummary(Object oTS)
{   if (null oTS or oTS is not a TestSummary) then return(-1)
    return(CountTestProcedures(oTS)
}


-Louie

 

Hi Ilandale,

Again, thank you very much for quick reply, and your solution did help me :-)

My final dxl code ended up looking like this.
/////////////////////////// constant declarations ///////////////////////
const string attrName = "Result" // attribute to test
const string attrVal = "Failed" // attribute value to test

////////////////////////// variable declarations /////////////////////////
int iCount = 0
string attr = ""
Object oChild

void MakeTestSetSummary(Object oHead)
{
if (null oHead) then return -88
for oChild in oHead do
{
if (probeAttr_(oChild, attrName ) != "")
{
attr = oChild.attrName
}
else
{
attr = ""
}
if (attr == attrVal)
{
iCount++
}
MakeTestSetSummary(oChild) // traverse all childs recursively
}
}

if (level(obj) == 2)
{
MakeTestSetSummary(obj)
obj.attrDXLName = iCount
}
else
{
obj.attrDXLName = ""
}